﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Principal;
using Universum.Model.Services.QuestionIt;
using System.Web.Mvc;
using Universum.Views.QuestionIt;
using Universum.Model.Domain.QuestionIT;
using Universum.Infrastructure.Utils;
using System.Text;
using Universum.Model.Services;
using System.Collections;
using Universum.Infrastructure.Configuration;

namespace Universum.Controllers
{
	[Authorize]
	public class QuestionItController : UniversumController
	{
		const string VIEW_INDEX = "Index";
		IQuestionService _Service;
		IFriendlyUrlService _SlugService;
		
		const string acceptedPropertiesOnCreateAndUpdate
		 = "Title,Text";
		
		public QuestionItController(IPrincipal principal
			,IQuestionService questionService
			,IFriendlyUrlService slugService
			
			)

			:base(principal)
		{

			_SlugService = slugService;
			_Service = questionService;
		}

		public ActionResult RefreshQuestion(Guid id/*question id*/)
		{
			return PartialView("DisplayUC",_Service.GetQuestionById(id));
		}

		public ActionResult Index(int id)
		{
			if (ConstantIdentifiers.SPECIAL_USER == CurrentUsername)
			{
				return RedirectToAction<QuestionItController>(it => it.OffensiveQuestion(1));
			}
			QuestionIndexViewModel viewModel = new QuestionIndexViewModel();

			viewModel.QuestionsCount = _Service.GetQuestionsCount();
			viewModel.QuestionsPerPage = Universum.Infrastructure.Configuration.ConstantIdentifiers.RESULTS_PER_PAGE;
			viewModel.StartIndex = Math.Max(1,id);
			viewModel.Questions = _Service.GetQuestionsFor(viewModel.StartIndex-1, viewModel.QuestionsPerPage);

			ViewData.Model = viewModel;
			return View();
		}
		[Authorize(Users=ConstantIdentifiers.SPECIAL_USER)]
		public ActionResult OffensiveQuestion(int id)
		{
			QuestionIndexViewModel viewModel = new QuestionIndexViewModel();

			//viewModel.QuestionsCount = _Service.GetQuestionsCount();
			viewModel.QuestionsPerPage = Universum.Infrastructure.Configuration.ConstantIdentifiers.RESULTS_PER_PAGE;
			viewModel.StartIndex = Math.Max(1, id);
			viewModel.Questions = _Service.GetOffensiveQuestionsFor(viewModel.StartIndex - 1, viewModel.QuestionsPerPage);
			viewModel.QuestionsCount = viewModel.Questions.Count;

			ViewData.Model = viewModel;
			return View("Index");
		}

		public ActionResult Create()
		{
			return View();
		}
		[AcceptVerbs( HttpVerbs.Post)]
		[ValidateInput(false)]
		public ActionResult Create(
			[Bind(Include=QuestionItController.acceptedPropertiesOnCreateAndUpdate)]
			Question question)
		{
			if (ModelState.IsValid)
			{
				Question save = _Service.CreateQuestion();
				save.Slug = _SlugService.CreateSlugFrom(question.Title);
				save.Title = question.Title;
				save.Text = question.Text;
				_Service.SaveOrUpdate(save);
				return RedirectToAction<QuestionItController>(c => c.Index(0));
			}
			return View();
		}
		[AcceptVerbs( HttpVerbs.Post)]
		[ValidateInput(false)]
		public ActionResult SaveReply(
			[Bind(Include = "QuestionId,Text")]
			QuestionReply reply)
		{
			var question = _Service.GetQuestionById(reply.QuestionId);
			if ( question != null && this.ModelState.IsValid)
			{
				reply.ID = Guid.NewGuid();
				reply.Username = CurrentUsername;
				reply.Publish = reply.Created = DateTime.Now;
				
				_Service.SaveOrUpdateReply(reply);
			}
			return RedirectToAction<QuestionItController>(c => c.Show(question.Slug));
		}
		public ActionResult Unanswered(int id)
		{
			QuestionIndexViewModel viewModel = new QuestionIndexViewModel();

			viewModel.QuestionsCount = _Service.GetQuestionsCount();
			viewModel.QuestionsPerPage = Universum.Infrastructure.Configuration.ConstantIdentifiers.RESULTS_PER_PAGE;
			viewModel.StartIndex = Math.Max(1, id);
			viewModel.Questions = _Service.GetUnansweredQuestions(viewModel.StartIndex - 1, viewModel.QuestionsPerPage);

			ViewData.Model = viewModel;
			return View(VIEW_INDEX);
		}

		public ActionResult Answered(int id)
		{
			QuestionIndexViewModel viewModel = new QuestionIndexViewModel();

			viewModel.QuestionsCount = _Service.GetQuestionsCount();
			viewModel.QuestionsPerPage = Universum.Infrastructure.Configuration.ConstantIdentifiers.RESULTS_PER_PAGE;
			viewModel.StartIndex = Math.Max(1, id);
			viewModel.Questions = _Service.GetAnsweredQuestions(viewModel.StartIndex - 1, viewModel.QuestionsPerPage);

			ViewData.Model = viewModel;
			return View(VIEW_INDEX);
		}

		public ActionResult Hottest(int id)
		{
			QuestionIndexViewModel viewModel = new QuestionIndexViewModel();

			viewModel.QuestionsCount = _Service.GetQuestionsCount();
			viewModel.QuestionsPerPage = Universum.Infrastructure.Configuration.ConstantIdentifiers.RESULTS_PER_PAGE;
			viewModel.StartIndex = Math.Max(1, id);
			viewModel.Questions = _Service.GetHottestQuestions(viewModel.StartIndex - 1, viewModel.QuestionsPerPage);

			ViewData.Model = viewModel;
			return View(VIEW_INDEX);
		}

		public ActionResult PlusQuestionReply(Guid id)
		{

			var reply = _Service.GetQuestionReplyById(id);
			if (reply != null)
			{
				reply.Rating = reply.Rating + 1;
				_Service.SaveOrUpdateReply(reply);
			}
			return new EmptyResult();
		}
		public ActionResult MinusQuestionReply(Guid id)
		{
			var reply = _Service.GetQuestionReplyById(id);
			if (reply != null)
			{
				reply.Rating = reply.Rating - 1;
				_Service.SaveOrUpdateReply(reply);
			}
			return new EmptyResult();
		}

		public ActionResult Show(string id)
		{
			Question question = _Service.GetQuestionBySlug(id);
			IList<QuestionReply> replies = _Service.GetRepliesFor(question.ID);
			QuestionReply newReply = _Service.GetNewReplyFor(question.ID);
			QuestionShowViewModel viewModel = new QuestionShowViewModel();
			viewModel.Question = question;
			viewModel.Replies = replies;
			viewModel.NewReply = newReply;

			ViewData.Model = viewModel;
			
			return View();
		}
		[AcceptVerbs( HttpVerbs.Post)]
		public ActionResult PlusQuestion(Guid id)
		{
			_Service.PlusRatingOnQuestion(id, CurrentUsername);
			return new EmptyResult();
		}
		[AcceptVerbs( HttpVerbs.Post)]
		public ActionResult MinusQuestion(Guid id)
		{
			_Service.MinusRatingOnQuestion(id, CurrentUsername);
			return new EmptyResult();
		}

		[AcceptVerbs( HttpVerbs.Post)]
		public ActionResult MarkQuestionAsOffensive(Guid id)
		{
			var question = _Service.GetQuestionById(id);

			if (question != null)
			{
				_Service.MarkQuestionAsOffensive(question,CurrentUsername);
			}

			return new EmptyResult();
		}

		[AcceptVerbs( HttpVerbs.Post )]
		public ActionResult UnMarkQuestionAsOffensive(Guid id){
			var question = _Service.GetQuestionById(id);

			if (question != null)
			{
				_Service.UnMarkQuestionAsOffensive(question, CurrentUsername);
			}

			return new EmptyResult();
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult MarkQuestionReplyAsOffensive(Guid id)
		{
			var reply = _Service.GetQuestionReplyById(id);

			if (reply != null)
			{
				_Service.MarkQuestionReplyAsOffensive(reply);
			}

			return new EmptyResult();
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult UnMarkQuestionReplyAsOffensive(Guid id)
		{
			var reply = _Service.GetQuestionReplyById(id);

			if (reply != null)
			{
				_Service.UnMarkQuestionReplyAsOffensive(reply);
			}

			return new EmptyResult();
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult MarkQuestionReplyAsAnswer(Guid id)
		{
			var reply = _Service.GetQuestionReplyById(id);
			if (reply != null)
			{
				var question = _Service.GetQuestionById(reply.QuestionId);
				if (question.Username == User.Identity.Name)
				{
					_Service.MarkQuestionReplyAsAnswer(reply);
					_Service.MarkQuestionAsAnswered(question);
				}
			}
			return new EmptyResult();
		}


		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult UnMarkQuestionReplyAsAnswer(Guid id)
		{
			var reply = _Service.GetQuestionReplyById(id);
			if (reply != null)
			{
				var question = _Service.GetQuestionById(reply.QuestionId);
				if (question.Username == User.Identity.Name)
				{
					_Service.UnMarkQuestionReplyAsAnswer(reply);
					_Service.UnMarkQuestionAsAnswered(question);
				}
			}
			return new EmptyResult();
		}
		public ActionResult EditReply(Guid id)
		{
			ViewData.Model = _Service.GetQuestionReplyById(id);
			return View();
		}
		[AcceptVerbs( HttpVerbs.Post)]
		[ValidateInput(false)]
		
		public ActionResult EditReply([Bind(Include="ID,Title,Text")]QuestionReply reply)
		{
			var oldReply  = _Service.GetQuestionReplyById(reply.ID);
			if (oldReply != null && oldReply.Username == User.Identity.Name)
			{
				oldReply.Text = reply.Text;
				oldReply.Title = reply.Title;
				return RedirectToAction<QuestionItController>(
					c=>c.Show( _Service.GetQuestionById(reply.QuestionId).Slug ));
			}
			return View();
		}
		[AcceptVerbs(HttpVerbs.Post)]
		[ValidateInput(false)]
	
		public ActionResult EditQuestion(	[Bind(Include = "ID,Title,Text")]Question question)
		{
			var oldQuestion  = _Service.GetQuestionById(question.ID);
			if (oldQuestion != null && oldQuestion.Username == User.Identity.Name)
			{
				oldQuestion.Text = question.Text;
				oldQuestion.Title = question.Title;
				oldQuestion.Slug = _SlugService.CreateSlugFrom(oldQuestion.Title);
				_Service.SaveOrUpdate(oldQuestion);
				return RedirectToAction<QuestionItController>(
					c => c.Show(oldQuestion.Slug));
			}
			return View();
		}

		public ActionResult EditQuestion(Guid id)
		{
			ViewData.Model = _Service.GetQuestionById(id);
			return View();
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult RemoveQuestion(Guid id)
		{
			var question = _Service.GetQuestionById(id);

			if (question != null && question.Username == User.Identity.Name)
			{
				_Service.RemoveQuestion(question);
			}

			return new EmptyResult();
		}
		[AcceptVerbs( HttpVerbs.Post)]
		public ActionResult RemoveReply(Guid id)
		{
			var reply = _Service.GetQuestionReplyById(id);

			if (reply.IsNotNull())
			{
				var question = _Service.GetQuestionById(reply.QuestionId);
				if (reply.Username == User.Identity.Name ||
					question.Username == User.Identity.Name)
				{
					_Service.RemoveQuestionReply(reply);
					return RedirectToAction<QuestionItController>(
						c => c.Show(question.Slug));
				}
			}
			return new EmptyResult();
		}
		[Authorize(Users = ConstantIdentifiers.SPECIAL_USER),
		AcceptVerbs( HttpVerbs.Post)]
		public ActionResult UnMarkQuestionAsOffensiveBySuperUser(Guid id)
		{
			_Service.UnMarkQuestionAsOffensiveBySuperUser(id);
			return RedirectToAction<QuestionItController>(it => it.OffensiveQuestion(1));
		}
	}
}
